package ui.message;

import entity.domain.DomainHelper;
import entity.domain.topic.ContinuousTopic;
import entity.domain.topic.DiscreteTopic;
import entity.domain.topic.Range;
import entity.domain.topic.Topic;
import entity.domain.value.Value;
import entity.evaluation.Evaluator;
import entity.evaluation.EvaluatorHelper;
import entity.evaluation.topic.ContinuousTopicEvaluator;
import entity.evaluation.topic.DiscreteTopicEvaluator;
import entity.evaluation.value.DiscreteValueEvaluator;
import entity.offer.bid.Bid;
import server.MessageHandler;
import ui.topic.ContinuousTopicPanel;
import ui.topic.DiscreteTopicPanel;
import ui.topic.TopicPanel;

import entity.domain.Domain;
import ui.topic.UpdateBidInfo;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GamePanel implements UpdateBidInfo{

    private JPanel gamePanel;
    private JPanel jp_sendingMsg;
    private JPanel jp_couterMsg;
    private JPanel jp_title;
    private JScrollPane jsp_servMsg;
    private JButton btn_agree;
    private JButton btn_send;
    private JTextArea ta_serMsg;
    private JTextArea ta_comment;
    private JPanel jp_topic;
    private JPanel jp_button;
    private JPanel jp_message;
    private JScrollPane jsp_counterMsg;
    private JLabel lbl_title;
    private JScrollPane jsp_bidInfo;
    private JScrollPane jsp_comment;
    private JScrollPane jsp_topic;
    private JPanel jp_counterMessage;
    private JTextArea ta_counterMessage;
    private JTextArea ta_bidInfo;
    private EvaluatorHelper helper;
    //private MessageHandler msgHandler;
    private Value[] values;
    private boolean isAccept;

    /*public GamePanel(){
        lbl_title.setText("Hello");
        for(int i = 0; i<4; i++){
            jp_topic.add(new DiscreteTopicPanel("A", new Object[]{1, 3, 5, 7}));
            jp_topic.add(new ContinuousTopicPanel("C", 3, 100));
        }
    }*/

    public GamePanel(String name, EvaluatorHelper helper, Object senderLock) {
        //this.msgHandler = msgHandler;
        lbl_title.setText(name);
        this.helper = helper;
        Evaluator evaluator = helper.getEvaluator();
        Domain domain = helper.getDomain();
        List<Topic> topics = domain.getTopics();
        for(int i = 0; i<topics.size(); i ++){
            Topic topic = topics.get(i);
            TopicPanel topicPanel = null;
            switch (topic.getType()){
                case Discrete:
                    DiscreteTopic discreteTopic = (DiscreteTopic) topic;
                    DiscreteTopicEvaluator discreteTopicEvaluator = (DiscreteTopicEvaluator) helper.getEvaluator().getTopicEvaluators().get(i);
                    String[] strs = new String[discreteTopic.getOptions().size()];
                    for(int j = 0; j<strs.length; j++){
                        strs[j] = discreteTopic.getOptions().get(j).toString()+"("+((DiscreteValueEvaluator)(discreteTopicEvaluator.getValueEvaluator().get(j))).getEvaluation()+")";
                    }
                    topicPanel = new DiscreteTopicPanel(topic.getName().toString(), discreteTopicEvaluator.getWeight(), strs, this);
                    jp_topic.add(topicPanel);
                    break;
                case Continuous:
                    Range range = ((ContinuousTopic) topic).getRange();
                    ContinuousTopicEvaluator continuousTopicEvaluator = (ContinuousTopicEvaluator) evaluator.getTopicEvaluators().get(i);
                    double offset = continuousTopicEvaluator.getValueEvaluator().getOffset();
                    double slope = continuousTopicEvaluator.getValueEvaluator().getSlope();
                    double dest = offset + slope*(range.getUpperbound() - range.getLowerbound());
                    topicPanel = new ContinuousTopicPanel(topic.getName(), continuousTopicEvaluator.getWeight(), (int)range.getLowerbound(), (int)range.getUpperbound(), offset, dest, this);
                    jp_topic.add(topicPanel);
                    break;
            }
        }
        this.values = getBidInput();
        btn_send.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (senderLock){
                    values = getBidInput();
                    isAccept = false;
                    senderLock.notify();
                }
            }
        });
        btn_agree.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                synchronized (senderLock){
                    values = getBidInput();
                    isAccept = true;
                    senderLock.notify();
                }
            }
        });
    }

    private Value[] getBidInput(){
        Component[] components = jp_topic.getComponents();
        int num = components.length;
        Value[] values = new Value[num];
        for(int i = 0; i<num; i++){
            values[i] = ((TopicPanel) components[i]).getValue();
        }
        return values;
    }

    public Value[] getValues() {
        return values;
    }

    public String getCommentInput(){
        return ta_comment.getText();
    }

    public boolean getIsAccept(){
        return isAccept;
    }

    @Override
    public void updateBidInfo(){
        Bid bid = new Bid(Arrays.asList(getBidInput()));
        double evaluation = helper.getNormalizedEvaluation(bid);
        ta_bidInfo.setText("My utility: "+evaluation);
    }

    public void displayCounterMessage(String sender, String time, String bidInfo, double evaluation, String comment) {
        ta_counterMessage.append("Player: "+sender+"\t"+time+"\n");
        ta_counterMessage.append("My utility: "+String.valueOf(evaluation)+"\n");
        ta_counterMessage.append("Counter offer: "+bidInfo+"\n");
        ta_counterMessage.append("Comment: "+comment+"\n\n");
    }

    public void displayServerMessage(String time, String message){
        ta_serMsg.append("\n"+time+"\t"+message);
    }

    public void setSendButtonEnabled(boolean enabled){
        btn_send.setEnabled(enabled);
    }

    public void setButtonEnabled(boolean enabled){
        btn_send.setEnabled(enabled);
        btn_agree.setEnabled(enabled);
    }

    /*public static MessageFrame createMessageFrame(String title, Domain domain, MessageHandler msgHandler) {
        MessageFrame frame = new MessageFrame();
        frame.setContentPane(new GamePanel(title, domain, msgHandler).gamePanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        return frame;
    }*/

    public static GamePanel createMessagePanel(String title, EvaluatorHelper helper, Object senderLock) {
        JFrame frame = new JFrame("人机间智能协商平台");
        GamePanel panel = new GamePanel(title, helper, senderLock);
        frame.setContentPane(panel.gamePanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        return panel;
    }


}
